-
Notifications
You must be signed in to change notification settings - Fork 874
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[NETBEANS-4123] Initial implementation of handling large strings #5299
Conversation
This is intended to (mostly) fix #4123 |
java/debugger.jpda/src/org/netbeans/modules/debugger/jpda/models/ShortenedStrings.java
Outdated
Show resolved
Hide resolved
java/debugger.jpda/src/org/netbeans/modules/debugger/jpda/models/ShortenedStrings.java
Outdated
Show resolved
Hide resolved
java/debugger.jpda/src/org/netbeans/modules/debugger/jpda/models/ShortenedStrings.java
Outdated
Show resolved
Hide resolved
java/debugger.jpda/src/org/netbeans/modules/debugger/jpda/models/ShortenedStrings.java
Outdated
Show resolved
Hide resolved
Please add the necessary imports - the proposed changes also need corresponding import adjustments. Thank you. |
Ya. I am aware. I am still working in it. I did find out how to grab the hi byte field, so I added logic in for that. I will get to that tomorrow. |
private static boolean isSmallEndian(VirtualMachine virtualMachine) { | ||
//TODO: Possibly cache this value | ||
List<ReferenceType> possibleClasses = virtualMachine.classesByName( | ||
"java.lang.StringUTF16"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this should be cacheable with a WeakHashMap using the Virtualmachine as Key. This might be slow if the target VM is not local. I experimented a bit with this code and on JDK 17 initially possibleClasses
was empty for me. Not sure how the VM handled this interernally, but I could make it work using this code:
if (possibleClasses.isEmpty()) {
ClassType ct = (ClassType) virtualMachine.classesByName("java.lang.Class").iterator().next();
Method m = ct.concreteMethodByName("forName", "(Ljava/lang/String;)Ljava/lang/Class;");
StringReference referenceString = virtualMachine.mirrorOf("java.lang.StringUTF16");
try {
ThreadReference threadReference = virtualMachine.allThreads().get(0);
ct.invokeMethod(threadReference, m, Collections.singletonList(referenceString), 0);
possibleClasses = virtualMachine.classesByName("java.lang.StringUTF16");
} catch (InvalidTypeException | ClassNotLoadedException | IncompatibleThreadStateException | InvocationException ex) {
Exceptions.printStackTrace(ex);
}
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Aye. Will get to that. Do we need to handle multiple threads or are we good without using concurrent structures here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In my test I had to make isSmallEndian
synchronized - else I got into a IncompatibleThreadStateException
. Not really sure whether this hammer just fixed the problem accidentally.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok. Should I slap a synchronized
onto it, not worry about it, or find another solution?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Works for me and looks sane. The caching you introduced works (at least in my trivial testcase).
One final idea would be to rework the synchronization. The maps are protected by individual sychronized() {}
blocks. The pattern could be applied here two, which would also not leak the sychronization to the outside.
My suggestion is to move the isLittleEndianCache.clear();
into a separate block synchronized (isLittleEndianCache) {isLittleEndianCache.clear();}
, drop the synchronized
from the signature of isLittleEndian
and instead wrap the whole method contents into a synchronized (isLittleEndianCache) {....}
block.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Final cleanup (see inline comments). Please also squash the commits into a single one.
java/debugger.jpda/src/org/netbeans/modules/debugger/jpda/models/ShortenedStrings.java
Show resolved
Hide resolved
java/debugger.jpda/src/org/netbeans/modules/debugger/jpda/models/ShortenedStrings.java
Outdated
Show resolved
Hide resolved
java/debugger.jpda/src/org/netbeans/modules/debugger/jpda/models/ShortenedStrings.java
Outdated
Show resolved
Hide resolved
java/debugger.jpda/src/org/netbeans/modules/debugger/jpda/models/ShortenedStrings.java
Outdated
Show resolved
Hide resolved
java/debugger.jpda/src/org/netbeans/modules/debugger/jpda/models/ShortenedStrings.java
Outdated
Show resolved
Hide resolved
While applying those changes, noticed that |
I have mixed feelings here. The use sites don't give information about what went wrong, which would make it hard to debug. What would you think about this idea: let |
Pushing the exception lift change so it can be reviewed before squishing everything |
To me this looks sane, thank you. It is an impressive list of Exceptions and we might want to refactor these calls later, but I think as a fix for the issue at hand this should be merged. I requested a first CI run and the system is happy. So, I suggest that you squash the commit as you see fit. I would suggest to squash into a single commit as all commit cover the same area and there are not really smaller building blocks. If then GH actions is happy, I'll merge. |
In the debugger (+7 squashed commits) Squashed commits: [5e45018] [NETBEANS-4123] Lifted exceptions from ShortenedStrings.isLittleEndian Waiting for this change to be reviewed before squishing [fc97d86] [NETBEANS-4123] Checkpoint before extracting exceptions... [e6cedcd] [NETBEANS-4123] Moved sync blocks around as per @matthiasblaesing [1b1da08] [NETBEANS-4123] Now caching whether or not a VM is little endian Check is now deferred to when it is needed instead of right away. [4f52c49] [NETBEANS-4123] Finished implementing the handling of long strings Renamed 'compressed' things to 'compact' Tested with a long UTF16 string on little endian. It detects the byte order properly [e8d001f] [NETBEANS-4123] Apply suggestions from code review Will apply other changes and testing in a bit since you can't do those in GitHub Co-authored-by: Matthias Bläsing <mblaesing@doppel-helix.eu> [2caef56] [NETBEANS-4123] Initial implementation of handling large strings in Java 9+ where the String class uses a byte[] instead of a char[]
5e45018
to
b5a597f
Compare
And squashed |
Thank you. As the unittests finally run cleanly through, lets get this in. |
in Java 9+ where the String class uses a byte[] instead of a char[]
Not a final implementation at the moment, but should be enough for now. I didn't see any tests related to this class, so I didn't write any. I have tested it and it works properly. May need more testing.
Handling UTF16 byte[] strings would require more effort since it becomes a nightmare.